﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
using WeManageService;

namespace WeManageForm.Report
{
	public partial class PeriodicForm : Form
	{
		public int currentPage;
		public List<List<string>> Reports = new List<List<string>>();
		public List<Label> currentLabel = new List<Label>();

		public void AddPage(params string[] vs)
		{
			List<string> strs = new List<string>(vs);
			Reports.Add(strs);
		}

		public int GetMaxIndex(params int[] vs)
		{
			List<int> vsSorted = new List<int>(vs);
			vsSorted.Sort();
			return vs.ToList().IndexOf(vsSorted.Last());
		}

		public PeriodicForm(int function)
		{
			string[] WeekDays = new string[7] { "星期日", "星期一", "星期二", "星期三", "星期四", "星期五", "星期六" };

			InitializeComponent();
			
			if(function == 0) //周报
			{
				AddPage(Global.UserName, "欢迎来到周报", "来看看你本周的任务完成情况吧");
				DateTime ReportTime = Global.SundayThisWeek;
				DateTime MaxTime = ReportTime;
				DateTime MinTime = ReportTime;
				DateTime MaxQualityTime = ReportTime;
				int maxv = Reporter.GetFinishPlanByTime(ReportTime, ReportTime.AddDays(1));
				int minv = Reporter.GetFinishPlanByTime(ReportTime, ReportTime.AddDays(1));
				decimal maxq = maxv == 0 ? 0 : (decimal)Reporter.GetScoreByTime(ReportTime, ReportTime.AddDays(1)) / maxv;
				for (int i = 1; i < 7; i++)
				{
					int nowv = Reporter.GetFinishPlanByTime(ReportTime.AddDays(i), ReportTime.AddDays(i + 1));
					decimal nowq = nowv == 0 ? 0 : (decimal)Reporter.GetScoreByTime(ReportTime.AddDays(i), ReportTime.AddDays(i + 1)) / nowv;
					if(nowv > maxv)
					{
						maxv = nowv;
						MaxTime = ReportTime.AddDays(i);
					}
					if(nowv < minv)
					{
						minv = nowv;
						MinTime = ReportTime.AddDays(i);
					}
					if (nowq > maxq)
					{
						maxq = nowq;
						MaxQualityTime = ReportTime.AddDays(i);
					}
				}
				if (maxv == 0)
				{
					AddPage("这周你没有完成任何任务", "因此我们无法", "对你的任务完成状况进行分析 :(");
				}
				else
				{
					AddPage($"在 {MaxTime.Month}月{MaxTime.Day}日 {WeekDays[(int)MaxTime.DayOfWeek]}", 
						"你完成了 " + maxv.ToString() + " 个任务",  "这一天你很勤奋", "继续努力");
					
					if(maxv != minv)
						AddPage("在 " + $"{MinTime.Month}月{MinTime.Day}日 {WeekDays[(int)MinTime.DayOfWeek]}",
							"你完成了 " + minv.ToString() + " 个任务", "劳逸结合", "亦不失为一种智慧");

					AddPage($"在 {MaxQualityTime.Month}月{MaxQualityTime.Day}日 {WeekDays[(int)MaxQualityTime.DayOfWeek]}",
						$"你对自己的平均评价为 {maxq:F2}" , "把量的合理增长和质的稳步提升有机统一起来", "是走向成功的秘诀");
				}
				AddPage("以上就是全部周报内容了", "新的一周也要加油哦！");
			}
			else //月报
			{
				AddPage(Global.UserName, "月报来了", "请查收");
				DateTime ReportTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month,1);
				DateTime ReportEndTime = new DateTime(DateTime.Now.Year, DateTime.Now.Month + 1, 1);
				DateTime MaxTime = ReportTime;
				DateTime MinTime = ReportTime;
				DateTime MaxQualityTime = ReportTime;
				DateTime MaxTLETime = ReportTime;
				int maxv = Reporter.GetFinishPlanByTime(ReportTime, ReportTime.AddDays(1));
				int minv = Reporter.GetFinishPlanByTime(ReportTime, ReportTime.AddDays(1));
				decimal maxq = maxv == 0 ? 0 : (decimal)Reporter.GetScoreByTime(ReportTime, ReportTime.AddDays(1)) / maxv;
				int maxtle = Reporter.GetUnfinishPlanByTime(ReportTime, ReportTime.AddDays(1));
				int totalMidnight = 0, totalMorning = 0, totalAfternoon = 0, totalEvening = 0;
				int weekday = 0, weekend = 0, weekdayv = 0, weekendv = 0;
				for (int i = 0; ReportTime.AddDays(i) < ReportEndTime; i++)
				{
					int nowMidnight = Reporter.GetFinishPlanByTime(ReportTime.AddDays(i), ReportTime.AddDays(i).AddHours(6));
					int nowMorning = Reporter.GetFinishPlanByTime(ReportTime.AddDays(i).AddHours(6), ReportTime.AddDays(i).AddHours(12));
					int nowAfternoon = Reporter.GetFinishPlanByTime(ReportTime.AddDays(i).AddHours(12), ReportTime.AddDays(i).AddHours(18));
					int nowEvening = Reporter.GetFinishPlanByTime(ReportTime.AddDays(i).AddHours(18), ReportTime.AddDays(i).AddHours(24));
					int nowv = nowMidnight + nowMorning + nowAfternoon + nowEvening;
					if(ReportTime.AddDays(i).DayOfWeek == DayOfWeek.Saturday || ReportTime.AddDays(i).DayOfWeek == DayOfWeek.Sunday)
					{
						weekend++;
						weekendv += nowv;
					}
					else
					{
						weekday++;
						weekdayv += nowv;
					}
					totalMidnight += nowMidnight;
					totalMorning += nowMorning;
					totalAfternoon += nowAfternoon;
					totalEvening += nowEvening;
					decimal nowq = nowv == 0 ? 0 : (decimal)Reporter.GetScoreByTime(ReportTime.AddDays(i), ReportTime.AddDays(i + 1)) / nowv;
					int nowtle = Reporter.GetUnfinishPlanByTime(ReportTime.AddDays(i), ReportTime.AddDays(i + 1));
					if (nowv > maxv)
					{
						maxv = nowv;
						MaxTime = ReportTime.AddDays(i);
					}
					if (nowv < minv)
					{
						minv = nowv;
						MinTime = ReportTime.AddDays(i);
					}
					if (nowq > maxq)
					{
						maxq = nowq;
						MaxQualityTime = ReportTime.AddDays(i);
					}
					if (nowtle > maxtle)
					{
						maxtle = nowtle;
						MaxTLETime = ReportTime.AddDays(i);
					}
				}
				if (maxv == 0)
				{
					AddPage("这个月你没有完成任何任务", "因此我们无法", "对你的任务完成状况进行分析 :(");
				}
				else
				{
					AddPage($"在 {MaxTime.Month}月{MaxTime.Day}日 {WeekDays[(int)MaxTime.DayOfWeek]}",
						"你完成了 " + maxv.ToString() + " 个任务", "这一天你很勤奋", "继续努力");

					if (maxv != minv)
						AddPage("在 " + $"{MinTime.Month}月{MinTime.Day}日 {WeekDays[(int)MinTime.DayOfWeek]}",
							"你完成了 " + minv.ToString() + " 个任务", "劳逸结合", "亦不失为一种智慧");

					AddPage($"在 {MaxQualityTime.Month}月{MaxQualityTime.Day}日 {WeekDays[(int)MaxQualityTime.DayOfWeek]}",
						$"你对自己的平均评价为 {maxq:F2}", "把量的合理增长和质的稳步提升有机统一起来", "是走向成功的秘诀");

					if(maxtle != 0)
						AddPage($"在 {MaxTLETime.Month}月{MaxTLETime.Day}日 {WeekDays[(int)MaxTLETime.DayOfWeek]}",
							$"你有 {maxtle} 个任务超时未完成", "是否对自己的欲望过于放纵？");
					
					switch(GetMaxIndex(totalMidnight, totalMorning, totalAfternoon, totalEvening))
					{
						case 0: AddPage("你最喜欢在夜深人静时学习工作", "还是要养成早睡早起的好习惯哦"); break;
						case 1: AddPage("你最喜欢在早上学习工作", "一日之计在于晨", "好的开始是成功的一半"); break;
						case 2: AddPage("你最喜欢在下午学习工作", "午休能让你的效率更高哦"); break;
						case 3: AddPage("你最喜欢在晚上学习工作", "看来是夜猫子呢", "注意补充营养", "才能不脱发"); break;
					}

					if (weekday * weekendv > weekend * weekdayv)
						AddPage("你更喜欢在周末完成预定的任务", "在利用闲暇时间的同时", "也要注意把握好劳逸结合");
					else AddPage("比起周末，你更喜欢在工作日完成任务", "利用好闲暇时间", "也是不错的选择");
				}
				switch (ReportTime.Month)
				{
					case 1: AddPage("以上就是月报的全部内容了", "春节将至", "祝新春快乐"); break;
					case 2: AddPage("以上就是月报的全部内容了", "祝你在新的一年里", "万事如意"); break;
					case 4: AddPage("以上就是月报的全部内容了", "五一将至", "要不给自己放个假？"); break;
					case 5: AddPage("以上就是月报的全部内容了", "五月的第二个星期日是母亲节", "记得为母亲送上祝福"); break;
					case 6: AddPage("以上就是月报的全部内容了", "端午节是农历五月初五", "祝愿美好生活", "接“粽”而至"); break;
					case 9: AddPage("以上就是月报的全部内容了", "中秋佳节", "祝团团圆圆"); break;
					case 12: AddPage("以上就是月报的全部内容了", "新年将至", "在新的一年中也要继续加油哦"); break;
					default: AddPage("以上就是月报的全部内容了", "在新的一月中也要继续加油哦"); break;
				}
			}
			currentPage = 1;
			ShowInitialPage();
		}
		
		private void ShowInitialPage()
		{
			switch (currentPage % 4)
			{
				case 0: pictureBox.Image = WeManageForm.Properties.Resources.food1; break;
				case 1: pictureBox.Image = WeManageForm.Properties.Resources.food2; break;
				case 2: pictureBox.Image = WeManageForm.Properties.Resources.food3; break;
				case 3: pictureBox.Image = WeManageForm.Properties.Resources.food4; break;
			}
			btnPrev.Enabled = false;
			btnNext.Enabled = false;

			List<Label> oldLabel = currentLabel;
			currentLabel = new List<Label>();

			foreach (string reportMessage in Reports[currentPage - 1])
			{
				Label label = new Label();
				label.Text = reportMessage;
				label.Location = new Point(5, currentLabel.Count * 40 + 40);
				label.AutoSize = true;
				label.Font = new Font("宋体", 11);
				currentLabel.Add(label);
				labelPanel.Controls.Add(label);
			}

			if (currentPage > 1) btnPrev.Enabled = true;
			if (currentPage < Reports.Count) btnNext.Enabled = true;
		}

		private void ShowCurrentPage()
		{
			switch(currentPage % 4)
			{
				case 0: pictureBox.Image = WeManageForm.Properties.Resources.food1; break;
				case 1: pictureBox.Image = WeManageForm.Properties.Resources.food2; break;
				case 2: pictureBox.Image = WeManageForm.Properties.Resources.food3; break;
				case 3: pictureBox.Image = WeManageForm.Properties.Resources.food4; break;
			}
			btnPrev.Enabled = false;
			btnNext.Enabled = false;

			List<Label> oldLabel = currentLabel;
			currentLabel = new List<Label>();

			foreach (string reportMessage in Reports[currentPage - 1])
			{
				Label label = new Label();
				label.Text = reportMessage;
				label.Location = new Point(5, currentLabel.Count * 40 + 40);
				label.AutoSize = true;
				label.Visible = false;
				label.Font = new Font("宋体", 11);
				currentLabel.Add(label);
				labelPanel.Controls.Add(label);
			}

			Thread thread = new Thread(() =>
			{
				if (oldLabel.Count != 0)
				{
					for (int i = 0; i <= 10; i++)
					{
						foreach (Label label in oldLabel)
						{
							if (!label.IsHandleCreated) label.CreateControl();
							label.Invoke(new Action(() => label.ForeColor = Color.FromArgb(135 * i / 10, 206 * i / 10, 250 * i / 10)));
						}
						
						Thread.Sleep(100);
					}
					if (!labelPanel.IsHandleCreated) labelPanel.CreateControl();
					labelPanel.Invoke(new Action(() =>
					{
						foreach (Label label in oldLabel)
							labelPanel.Invoke(new Action(() => labelPanel.Controls.Remove(label)));
					}));
				}


				foreach (Label label in currentLabel)
				{
					if (!label.IsHandleCreated) label.CreateControl();
					label.Invoke(new Action(() => label.Visible = true));
					for (int i = 10; i >= 0; i--)
					{
						label.Invoke(new Action(() => label.ForeColor = Color.FromArgb(135 * i / 10, 206 * i / 10, 250 * i / 10)));
						Thread.Sleep(100);
					}
				}

				if (currentPage > 1) btnPrev.Invoke(new Action(() => btnPrev.Enabled = true));
				if (currentPage < Reports.Count) btnNext.Invoke(new Action(() => btnNext.Enabled = true));
			});


			foreach (Label label in oldLabel) label.HandleDestroyed += (_1, _2) => thread.Abort();
			foreach (Label label in currentLabel) label.HandleDestroyed += (_1, _2) => thread.Abort();

			thread.Start();
		}

		private void btnPrev_Click(object sender, EventArgs e)
		{
			if(currentPage > 1)
			{
				currentPage--;
				ShowCurrentPage();
			}
		}

		private void btnNext_Click(object sender, EventArgs e)
		{
			if(currentPage < Reports.Count)
			{
				currentPage++;
				ShowCurrentPage();
			}
		}
	}
}
